package pikes.ecma;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import pikes.ecma.Addition;
import pikes.ecma.Assignment;
import pikes.ecma.FormattingScriptPrinter;
import pikes.ecma.FunctionDeclaration;
import pikes.ecma.Identifier;
import pikes.ecma.MemberPropertyAccess;
import pikes.ecma.SourceElements;
import pikes.ecma.VariableStatement;

public class ProgramTestCase {

	private StringBuilder appendable = null;

	private MockSyntaxTreeVisitor syntaxTreeVisitor = null;

	@Before
	public void setup() {
		appendable = new StringBuilder();
		syntaxTreeVisitor = new MockSyntaxTreeVisitor();
	}

	@Test
	public void emptyProgram() throws Exception {
		SourceElements program = new SourceElements();
		program.print(appendable);

		Assert.assertEquals("", appendable.toString());
		Assert.assertTrue(program.isEmpty());
	}

	@Test
	public void emptyProgramVisited() throws Exception {
		SourceElements program = new SourceElements();
		program.visit(syntaxTreeVisitor);

		Assert.assertNull(syntaxTreeVisitor.sourceElement);
		Assert.assertTrue(program.isEmpty());
	}

	@Test
	public void notEmptyProgram() throws Exception {
		SourceElements program = new SourceElements();
		MockSourceElement mockSource = new MockSourceElement();
		program.add(mockSource);

		program.visit(syntaxTreeVisitor);

		Assert.assertFalse(program.isEmpty());
		Assert.assertSame(syntaxTreeVisitor, mockSource.syntaxTreeVisitor);
	}

	@Test
	public void complexProgram() throws Exception {
		SourceElements program = new SourceElements();
		FunctionDeclaration funcDec = new FunctionDeclaration("go");
		funcDec.add("country");

		String url = "url";
		VariableStatement varDec = new VariableStatement(url, new Addition(new Identifier(
				"\"/countries/main/detail.htm?code=\""), new Identifier("country")));
		funcDec.add(varDec);
		funcDec.add(new Assignment(new MemberPropertyAccess("window", "location"), url));

		program.add(funcDec);

		program.print(appendable);

		Assert.assertEquals(
				"function go(country){var url=\"/countries/main/detail.htm?code=\"+country;window.location=url;}",
				appendable.toString());
	}

	@Test
	public void complexProgram1() throws Exception {
		SourceElements program = new SourceElements();
		FunctionDeclaration funcDec = new FunctionDeclaration("go");
		funcDec.add("country");

		String url = "url";
		VariableStatement varDec = new VariableStatement(url, new Addition(new Identifier(
				"\"/countries/main/detail.htm?code=\""), new Identifier("country")));
		funcDec.add(varDec);
		funcDec.add(new Assignment(new MemberPropertyAccess("window", "location"), url));

		program.add(funcDec);

		FormattingScriptPrinter printer = new FormattingScriptPrinter(appendable, true);
		printer.setSpaceBeforeOpeningBrace(true);
		printer.setStartBlockInNewLine(true);
		program.visit(printer);

		Assert.assertEquals(
				"function go(country) {\nvar url=\"/countries/main/detail.htm?code=\"+country;window.location=url;}",
				appendable.toString());
	}
}
